package com.ghc.zookeepermysql;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.TreeCache;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import java.util.List;

@SpringBootApplication
public class ZookeeperMysqlApplication {

    public static void main(String[] args) {
        SpringApplication.run(ZookeeperMysqlApplication.class, args);
    }

    public static String path = "/mysql";

    public static CuratorFramework curatorClient;

    public static DruidDataSource druidDataSource;
    /**
     * 注册监听
     * TreeCache: 可以将指定的路径节点作为根节点（祖先节点），对其所有的子节点操作进行监听，
     * 呈现树形目录的监听，可以设置监听深度，最大监听深度为 int 类型的最大值。
     */
    @Bean
    public void zkWatch() throws Exception {
        TreeCache treeCache = new TreeCache(getCuratorClient(), path);
        treeCache.getListenable().addListener(new TreeCacheListener() {
            public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
                ChildData eventData = event.getData();
                switch (event.getType()) {
                    case NODE_ADDED:
                        System.out.println(path + "节点添加" + eventData.getPath() + "\t添加数据为：" + new String(eventData.getData()));
                        if (druidDataSource == null || druidDataSource.isClosed()) {
                            druidDataSource = new DruidDataSource();
                        }
                        if (eventData.getPath().contains("username")){
                            druidDataSource.setUsername(new String(eventData.getData()));
                        }
                        if (eventData.getPath().contains("password")){
                            druidDataSource.setPassword(new String(eventData.getData()));
                        }
                        if (eventData.getPath().contains("url")){
                            druidDataSource.setUrl(new String(eventData.getData()));
                        }
                        if (eventData.getPath().contains("driverClass")){
                            druidDataSource.setDriverClassName(new String(eventData.getData()));
                        }
                        break;
                    case NODE_UPDATED:
                        System.out.println(eventData.getPath() + "节点数据更新\t更新数据为：" + new String(eventData.getData()) + "\t版本为：" + eventData.getStat().getVersion());
                        druidDataSource.close();
                        druidDataSource = new DruidDataSource();
                        List<String> strings = client.getChildren().forPath(eventData.getPath());
                        strings.forEach(key -> {
                            if (key.equals("username")){
                                druidDataSource.setUsername(new String(eventData.getData()));
                            }
                            if (key.equals("password")){
                                druidDataSource.setPassword(new String(eventData.getData()));
                            }
                            if (key.equals("url")){
                                druidDataSource.setUrl(new String(eventData.getData()));
                            }
                            if (key.equals("driverClass")){
                                druidDataSource.setDriverClassName(new String(eventData.getData()));
                            }
                        });
                        break;
                    case NODE_REMOVED:
                        System.out.println(eventData.getPath() + "节点被删除");
                        druidDataSource.close();
                        break;
                    default:
                        break;
                }
            }
        });
        treeCache.start();
    }

    public static CuratorFramework getCuratorClient(){
        if (curatorClient == null){
            RetryPolicy exponentialBackoffRetry = new ExponentialBackoffRetry(1000, 3);
            //使用fluent变成风格
            curatorClient = CuratorFrameworkFactory.builder()
                    .connectString("127.0.0.1:2181")
                    .sessionTimeoutMs(5000)
                    .connectionTimeoutMs(3000)
                    .retryPolicy(exponentialBackoffRetry)
                    .namespace("base")  //独立的命名空间
                    .build();
            curatorClient.start();
        }
        return curatorClient;
    }

}
